{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# GEM Cookbook\n",
    "\n",
    "This notebook aims to provide an introduction to the usage of the gym-electric-motor (GEM) toolbox. The first section introduces the basic building blocks of every GEM-environment. Afterwards, an introduction on how to quickly setup a  standard-environment is given. Finally, it is shown how to customize a GEM-environment to your personal needs."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.    Overview\n",
    "\n",
    "The gym-electric-motor (GEM) package is a Python toolbox for the simulation and control of various electric motors.\n",
    "\n",
    "It is built upon [Farama Gymnasium Environments](https://gymnasium.farama.org/), and, therefore, can be used for both, classical control simulation and reinforcement learning experiments. It allows you to construct a typical drive train with the usual building blocks, i.e. supply voltages, converters, electric motors and load models, and obtain not only a closed-loop simulation of this physical structure, but also a rich interface for plugging in any decision making algorithm, from PI-controllers to [Deep Deterministic Policy Gradient](https://spinningup.openai.com/en/latest/algorithms/ddpg.html) agents.\n",
    "\n",
    "### 1.1  Installation\n",
    "Before you can start, you need to make sure that you have gym-electric-motor installed. You can install it easily using pip:\n",
    "\n",
    "```\n",
    "pip install gym-electric-motor\n",
    "```\n",
    "    \n",
    "Alternatively, install the latest developer version directly from GitHub:\n",
    "https://github.com/upb-lea/gym-electric-motor\n",
    "\n",
    "For this notebook, we can install it by executing the following cell."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 Building Blocks\n",
    "A GEM environment consists of following building blocks:\n",
    "- Physical structure:\n",
    "   - Supply voltage\n",
    "   - Converter\n",
    "   - Electric motor\n",
    "   - Load model\n",
    "- Utility functions for reference generation, reward calculation and visualization\n",
    " \n",
    "#### Information Flow in a GEM Environment\n",
    "![](../../docs/plots/SCML_Overview.png)\n",
    "\n",
    "The following motor models are included:\n",
    "\n",
    "Four DC motors:\n",
    "\n",
    "- permanently excited motor\n",
    "- externally excited motor\n",
    "- series motor\n",
    "- shunt motor\n",
    "\n",
    "Three three phase symchronous motors:\n",
    "\n",
    "- PMSM (permanent magnet synchronous motor)\n",
    "- SynRM (synchronous reluctance motor)\n",
    "- EESM (externally excited synchronous motor)\n",
    "\n",
    "Two variants of the induction motor:\n",
    "\n",
    "- SCIM (squirrel cage induction motor)\n",
    "- DFIM (doubly fed induction motor)\n",
    "\n",
    "Following converters are included:\n",
    "\n",
    "- 1 quadrant converter (1QC)\n",
    "\n",
    "- 2 quadrant converter (2QC) as an asymmetric half bridge with both current polarities\n",
    "\n",
    "- 4 quadrant converter (4QC)\n",
    "\n",
    "- B6 bridge converter (B6C)\n",
    "\n",
    "All converters can consider interlocking times and a dead time of one sampling interval.\n",
    "Furthermore, they can be controlled with a finite control set (discrete set of actions) or continuous control set (continuous actions).\n",
    "\n",
    "Discrete actions are the direct switching states of the transistors.\n",
    "Continuous actions are the duty cycles for a pulse width modulation on the transistors. \n",
    "\n",
    "The actions are basically understood as the desired duty cycles. The actual applied voltage can be taken from the observations.\n",
    "The observations are normalized to their physical limits that can be accessed with `env.limits`.\n",
    "Therefore, all values are typically in a range of [0, 1] or [-1, 1]. \n",
    "\n",
    "All nominal values of voltages and currents are DC values in the case of a DC motor and peak phase values for the PMSM.\n",
    "Therefore, data sheet values for line voltage and phase currents of a PMSM has to be transformed with:\n",
    "$U_N = \\sqrt{\\frac{2}{3}}U_L$, $I_N = \\sqrt{2}I_S$.\n",
    "\n",
    "Moreover, the angular velocity is the mechanical one and not the electrical:\n",
    "$p\\omega_{me} = p\\omega = \\omega_{el}$\n",
    "\n",
    "### 1.3 Farama Gymnasium Interface\n",
    "Like every gymnasium environment, the basic user interface consists of four main functions.\n",
    "* `import gym_electric_motor as gem`    \n",
    "   Import the package. \n",
    "\n",
    "* `env = gem.make(environment-id, **kwargs)`  \n",
    "    Returns an instantiated motor environment. Call this function at the beginning.\n",
    "    The `gem.make()` method is equal to the `gym.make()`. By using `gem.make()`you can avoid importing gym additionally. \n",
    " \n",
    "* `initial_observation, info = env.reset()`  \n",
    "    Resets the motor. This includes a new initial state and new reference trajectories.\n",
    "    Call this function before a new episode starts. \n",
    "\n",
    "* `observation, reward, terminated, truncated, info = env.step(action)`      \n",
    "    This function performs one action on the environment for one time step.\n",
    "    It simulates the motor and needs to be called in every time step.\n",
    "    First, the voltage applied on the motor due to the converter output is determined and then an ODE solver is used to compute the next state. \n",
    "    Eventually, the reward is evaluated and returned together with the next observation and a flag indicating termination.\n",
    "    Several reward functions are available. The info is a dictionary that can be used in gym-environments to pass further information. It is not used within GEM. Thus, the dictionary is always empty.\n",
    "\n",
    "* `env.render()`    \n",
    "    Update the visualization of the motor states.\n",
    "    The signals to be displayed may be specified in the constructor-parameters of ```gem.make(**kwargs)```.\n",
    "    All visualizations are optional and should be disabled for increased computing speed.\n",
    "\n",
    "The observation in GEM-environments consists always of a tuple of the current environments state and the reference for the next time step. \n",
    "\n",
    "`(state, reference) = observation`"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.4 Basic Routine:"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-block alert-info\">  \n",
    "<b>Note:</b>    \n",
    "If the notebook is executed in <b>Colab</b>, the visualization cannot be used because dynamic matplotlib backends are not supported.\n",
    "</div>"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When the environment is run in a jupiter notebook, it is recommended to split the enviromnent creation and execution into two cells. Furthermore, the ``visu.initialize()`` call is required. The dashboard is per default the first (and only) visualization in an environment.\n",
    "\n",
    "If the environment is run from a script, the ``visu.initialize()`` call is not necessary. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\jakobeit\\Anaconda3\\envs\\GEMUpdate\\lib\\site-packages\\gymnasium\\core.py:311: UserWarning: \u001b[33mWARN: env.visualizations to get variables from other wrappers is deprecated and will be removed in v1.0, to get this variable you can do `env.unwrapped.visualizations` for environment variables or `env.get_wrapper_attr('visualizations')` that will search the reminding wrappers.\u001b[0m\n",
      "  logger.warn(\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "161b0ed12b47418bb434740e12dd00c0",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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79690bt3b6xatQpnz57Fnj178N577+Hpp59GREQE4uPjMXbsWLRp08YaNVvEtWvXUFVVhdatW0virVu3xo8//mjyPuXl5SgvLzde12q1AACdTgedTifJ1el0EAQBer0eer3ewtU3juzsbCxYsAAqlQrOzs54//33ERISgkGDBiE0NBRt2rRBjx496rWO8+fPBwCLPyaGE0YbHvM70ev1EAQBOp2O57K0AsNr4dbXBNkG+2E/2Av7wR4ACsGCX7Vw9epVpKSkICUlBb179zb+Z2+P8vPz0aZNGxw/fhyRkZHG+IIFC3D48GF89dVXte6zdOlSLFu2rFZ8+/btcHFxkcTUajV8fHzg7+8PBwcHy68ANVhFRQUuXryIwsJCVFZW2rocIiJqZKWlpXjiiSdQVFQEd3d3W5djExYdAJuSiooKuLi44LPPPsOIESOM8YSEBPzxxx9ITk6udR9TWwD9/f1RUFAALy8vSW5ZWRkuXryIwMBAyfnuyDoMRym7ubnddR/FsrIy5OXlwd/fn72xAp1Oh7S0NERHR0Oj0di6HNljP+wHe2E/tFotvL29ZT0AmnUamH379t3x9iFDhpizeKtycHBA165dcejQIeMAqNfrcejQIcycOdPkfRwdHU2e906j0dR6MVdVVUGhUECpVEKprNeultQAho99DY/5nSiVSigUCpN9I8vh42tf2A/7wV7YHh9/MwfATz/9FABw+fJlZGZmYuDAgRAEAenp6YiMjLTrARAA5s6di4SEBHTr1g0RERFYv349/vzzT0yePNnWpRERERFZjVkD4AcffAAAiIqKwtmzZ+Hj4wMAKCwsxPjx482vzsrGjBmDq1evYvHixSgsLER4eDj2799f68AQIiIioubE7G8CAcTzA9Y8sa+Xlxd+++03Syza6mbOnHnbj3yJiIiImiOLDICPP/44Hn74YYwcORIAkJSUxHO9EREREdkpiwyAS5cuxbBhw3Ds2DEAwDvvvIO///3vllg0EREREVmYRQ5PTUtLQ3BwMJ577jmo1Wps2rTptidTJiIiIiLbssgAOH/+fLRo0QInTpzA9u3bERUVhSlTplhi0URERERkYRY9QV1SUhKeeeYZPPbYYygtLbXkoomIiIjIQiyyD6Cfnx8mTJiAjIwMZGVloby8HFVVVZZYNBERERFZWJ23AE6YMAE3b94EAFy4cEFy22effYaRI0fi4MGDuOeee3D9+nWsXr3aspVSo5o2bRrGjRtn6zKIiIjICuq8BdDV1RXl5eVwdnZGYGAg7rnnHnTp0gXh4eEICwtDeHg4AgMDAQC+vr7w9fW1Vs3UCFasWGHya+9sbfLkyWjTpg1ee+01AEBmZiZ69eqF2NhYbN++3cbVERERNQ11HgA3bdpk/Dk3NxfZ2dnIyspCdnY2UlJSkJeXB7VajeDgYGRnZ1ulWGo8np6eti6hlqqqKqSmpmLv3r3GWGJiImbNmoXExEQUFBTI9ku9iYiI6qNB+wAGBAQgICAA8fHxxlhxcTGysrKQk5NjseLINvLy8tCuXTvk5uYat+rag+PHj0Oj0aB79+4AgJKSEuzcuROnTp1CQUEBtm/fjmXLltm4SiIiIvtnsaOA3dzc0Lt3b8yYMcNSiyQbyc7ORsuWLe1q+AOAlJQUxMXFQaFQAAB27dqF4OBgBAUFYdy4cfj4448hCIKNqyQiIrJ/Fj0NDDUPWVlZ6NKlS51yJ02ahNTUVCtXJEpOTpZsdU5MTMT48eMBAIMGDYJWq8Xhw4cbpRYiIqKmjAOgPaiqAnS66oteL8ZrxnS6uuVa4PQ72dnZCA8PN3s5lnT27Fnk5+dj4MCBAIBz587h5MmTxu+cVqvVGDlyJLZs2WLLMomIiJoEDoD2YPlywMGh+rJjhxh3camOtW8vxtauleYmJorxVq3E68uXm11OVlYWwsLCUFJSgkGDBiE0NBShoaE4cOAAAPG7n4OCgjBgwABcvnzZeL+8vDyEhYVh3LhxaN++PaZPn46kpCT06NEDnTt3xs8//2zMHTZsGLp27YrOnTvj448/BiAe0RsREYHKykpcvnwZ7du3R2FhIQDx49/o6Gg4OTkBELf+VVZWws/PD2q1Gg4ODtiyZQt2796NoqIisx8DIiKi5swiJ4ImM73yCvCPf1RfV6nEf019m8rcucCcObVzr14V/1WaN9NrtVrk5eUhPDwcBw4cgJeXF/bv3w9BEFBcXIyvv/4ae/fuRU5ODq5fv46OHTtK9vs8e/Ysdu3ahQcffBCdO3dGixYt8NVXX+G9997Dxo0b8eabbwIAtm3bBk9PT/z555/o3r07Ro8ejcjISPTp0wdvvPEGvv32WyxevBg+Pj4AxI9/n376aQBAZWUltm3bhjVr1iAmJgYAoNfrUVJSgokTJ2LHjh145plnzHociIiImjNuAbQHKhWg0VRfDENczZhGU7dcw0DYQNnZ2VCpVOjUqRNCQ0ORkZGBBQsW4MSJE3B3d8exY8cwcuRIODo6wtfXFwMGDJDcPygoCEFBQVCpVOjYsSOioqIAAKGhocjLyzPmrVu3DmFhYejZsycuXLhgPLn4a6+9hv/5n/9BWVkZJkyYAAC4cuUKTp06hWHDhgEAUlNTcePGDUyZMgWdO3c2XkJCQvDII48g0bBVlIiIiEziAEgS2dnZCA4OhqOjIzp06ICsrCx06tQJc+fOxcaNGwHAeBSuKTVPHq1UKo3XlUql8esB09PTcezYMXz11VfG31deXg5AHPYqKipw7do1Y/6ePXsQEREBb29vAOLHv1FRUfDw8Kj1+x955BGcOnWKpyMiIiK6Aw6AJDFz5kycOXMGAJCfnw9XV1ckJCRgzpw5yMrKQq9evZCUlISKigoUFhYiPT293r9Dq9XCy8sLTk5OxpOJG0ydOhUbNmxA9+7dsWbNGgC1j/7ds2eP5GTQNUVEREAQhDofxUxERCRHTW4AzMvLw5QpU9CuXTs4OzvjgQcewJIlS1BRUSHJUSgUtS4nTpyQLOvTTz9FcHAwnJycEBoain379jX26ti1M2fOoHv37ggPD8f69esxd+5cdOvWDYMHD0ZoaCieeOIJPPTQQ/Ve7qBBg1BcXIyQkBD885//RNeuXQGIW/buvfdeDB06FCtXrsSHH36Ic+fOoVevXsajfYmIiMh8CqGJnTl3//792LlzJ8aOHYsHH3wQ3333HaZOnYoJEyZg9erVAKq/yeLgwYPo1KmT8b5eXl7Q/LUv3fHjx9GnTx+sWLECw4YNw/bt2/HGG2/gm2++QefOnetUi1arhYeHB65duwYvLy/JbWVlZcjNzUW7du2MR66S9ej1emi1Wri7u0N5lwNh2Bvr0ul02LdvH4YMGWJ8vZHtsB/2g72wH4b/v4uKimT7FaJN7ijgQYMGYdCgQcbr999/P86dO4d3333XOAAaeHl5GY8ivdWbb76JQYMG4YUXXgAALF++HGlpadi4caPke4+JiIiImpsmNwCaUlRUBE9Pz1rx+Ph4lJWVoUOHDliwYIFkP7LMzEzMnTtXkh8bG4ukpKTb/p7y8nLjwQqA+BcEIP5VpzOcqPkvOp0OgiBAr9dDbzhZM1mNYUO24TG/E71eD0EQoNPpoDLzqGmqzfBauPU1QbbBftgP9sJ+sAfNYAA8f/48NmzYINn616JFC6xZswYPP/wwlEol/vOf/2DEiBFISkoyDoGFhYVo3bq1ZFmtW7c2nnjYlBUrVmDZsmW14unp6XBxcZHE1Go1fHx8UFJSItk/kayruLj4rjkVFRW4efMmMjIyUFlZ2QhVyVNaWpqtS6Aa2A/7wV7YXqmp8+zKjN3sA/jSSy/hjTfeuGPO2bNnERwcbLx+6dIl9O3bF/369cO///3vO9534sSJyM3NxZEjRwAADg4O+PDDDyUHF7zzzjtYtmyZ5NstajK1BdDf3x8FBQUm9wG8ePEiAgMDuZ9ZIzCcqNrNze2Op6kBxN7k5eXB39+fvbECnU6HtLQ0REdHcz8nO8B+2A/2wn5otVp4e3tzH0B7MG/ePEyaNOmOOffff7/x5/z8fPTv3x89e/bE5s2b77r8Hj16SP7q8vHxqTXoXb58+bb7DALiOe5qnufOQKPR1HoxV1VVQaFQQKlU3vWgBDKf4WNfw2N+J0qlEgqFwmTfyHL4+NoX9sN+sBe2x8ffjgbAVq1aoVWrVnXKvXTpEvr374+uXbvigw8+qNOAlZWVBV9fX+P1yMhIHDp0CHNqfK1aWloaIiMj6137nXD/P/vDnhARkdzZzQBYV5cuXUK/fv0QEBCA1atX46rhO3AB49a7Dz/8EA4ODvjb3/4GANi9eze2bNki+Zj4ueeeQ9++fbFmzRoMHToUn3zyCU6dOlWnrYl14eDgAKVSifz8fLRq1QoODg53/WiSGk6v16OiogJlZWW3/YNAEARUVFTg6tWrUCqVcHBwaOQqiYiI7EOTGwDT0tJw/vx5nD9/Hm3btpXcVnN3xuXLl+PXX3+FWq1GcHAwdu7cidGjRxtv79mzJ7Zv345FixZh4cKFaN++PZKSkup8DsC7USqVaNeuHQoKCpCfn2+RZdLtCYKAmzdvwtnZ+a6DtouLC+677z5+NE9ERLLV5AbASZMm3XVfwYSEBCQkJNx1WY8++igeffRRC1VWm4ODA+677z5UVlYav9eWrEOn0yEjIwN9+vS5474dKpUKarWaW2OJiEjWmtwA2NTwYIPGoVKpUFlZCScnJz7WREREd8HPwIiIiIhkhgMgERERkcxwACQiIiKSGQ6ARERERDLDAZCIiIhIZjgAEhEREckMB0AiIiIimeEASERERCQzPBG0Jeh04gUAVCpAqay+bqDRAFVVgF5fHatPrlIp5pvK1evFfEvmqtWAIJjOrawUb7tTrkIhxs3NBcT43XL1evF6zfW4Xa5KJd5marmmenRrLmB+P5tz7w0/3/qYWav39ck1t/dN8XkCiHk14/bwPGns94g79bOx3iMMP8v9PcJSzxOg4e8Rt/ZLjgRqsKKiIgGAUCQ+1cTLRx+JN6rV1bGAADG2alV1DBCEzZvFuIdHdczbW4xt3CjNXbdOjPv5VcdcXMTYBx9Ic197TYw/+KA0LgiCsGuXNLZwoRgPC5PGS0oEITVVGnvuOTG3Z09p/MoVQUhPl8aeekrMjYqSxnNzBeHkSWnsiSfE3OHDpfHvvhMvNWPDh4u5TzwhieuOHxcOvPeeNDcqSsx96ilpPD1drLlmrGdPMfe556Tx1FTxsagZCwsTcxculMZ37RLjNWMPPijGXntNGv/gAzHu4lId8/MTY+vWSXM3bhTj3t7VMQ8PMbZ5szR31SoxHhBQHVOrxdhHH0lzlywR4yEh0nhFhSB8/rk0Nn++mNutmzR+44YgfPmlJFb5zDNCUlKSUNWnjzT3t98E4ehRaSwhQVzukCHS+E8/CcK330pjo0eLuaNHS+Pffivm14wNGSLmJiRI40ePinXUjPXtK+Y++6w0/uWX4vrVjHXrJubOny+Nf/65+LjVjIWEiLlLlkjjjfweUVFRIZyeNUuaK8P3COHkSXHZNWON/B6h275dSEpKkubK8D1CePZZMbdvX2m8Ed8jiqKjBQBCUVGRIFcKQRAEWw+hTZVWq4WHhweuFRTAy8tLDHIrkKiR/7rX6fXY98UXGBITU/1VcNwC2LBcM3uvq6rCvgMHxF4Yeni75XILoOVyb9NPHYB9qakYEhtb/dqwg+eJHLcA6vR67Nu/H0Oio6VfWSmz9wh72AKoLS6Gh5cXioqK4O7uDjniR8CWoNGIl1tjt1KpxIup+5uTq1SKF0vnKhSmc9UmnjbWyr1dbbfm6nTick31oj7LtVaP5Nr7W5dtjd5bKtce+mmNXJ1OfMzr+j7VXN8jLJVrTo8Mg5SpXsj1PcKc3NvVVpfc2+XICA8CISIiIpIZDoBEREREMsMBkIiIiEhmOAASERERyQwHQCIiIiKZ4WEwZjCcQae4uFh6SD81Op1Oh9LSUmi1WvbCxtgL+8J+2A/2wn5otVoA1f+PyxEHQDP8/vvvAIB27drZuBIiIiKqr+LiYnh4eNi6DJvgAGgGT09PAMCFCxdk+wSyF1qtFv7+/rh48aJsT+ppL9gL+8J+2A/2wn4IgoDi4mL4+fnZuhSb4QBoBuVfJ6v08PDgi9lOuLu7sxd2gr2wL+yH/WAv7IPcN9zwIBAiIiIimeEASERERCQzHADN4OjoiCVLlsDR0dHWpcgee2E/2Av7wn7YD/aC7IlCkPMx0EREREQyxC2ARERERDLDAZCIiIhIZjgAEhEREckMB0AiIiIimeEASERERCQzHACJiIiIZIYDIBEREZHMcAAkIiIikhkOgEREREQywwGQiIiISGY4ABIRERHJDAdAIiIiIpnhAEhEREQkMxwAiYiIiGRGbesCmjK9Xo/8/Hy4ublBoVDYuhwiIiKqA0EQUFxcDD8/PyiV8twWxgHQDPn5+fD397d1GURERNQAFy9eRNu2bW1dhk1wADSDm5sbACA3Nxeenp42rkbedDodvvzyS8TExECj0di6HFljL+wL+2E/2Av7odVq4e/vb/x/XI44AJrB8LGvm5sb3N3dbVyNvOl0Ori4uMDd3Z1vrDbGXtgX9sN+sBf2R867b8nzg28iIiIiGeMASERERCQzHACJiIiIZIb7ADaCqqoq6HQ6W5fRrOl0OqjVapSVlaGqquq2eRqNBiqVqhErIyIisj8cAK1IEAQUFhbijz/+sHUpzZ4gCPDx8cHFixfvulNvy5Yt4ePjI+udf4mISN44AFqCTideAEClApRKQKdD4eXL+EOrxb2tWsGlRQsoAEAQqu+nUIgXvV66PKVSzLNlrmE4MpVrahk2ztUDKCkuRosWLaA03O+WXEEQUFpaiivXrgGCAN9WraTLVauBqirpY6FSibdVVkofH43GdO5fvbdorlIp5pvK1evFfEvmqtXiY2Yqt7JS2g9TuYafb33MTOUaHndTy711GZbINdXP+vS+KT5PADGvZtwenid36qc1nid36qelnyeA6R4Zfpb7e4SlnidAw98jbu2XDHEfQAvQ+PoCDg7iZccOAECVtzf+OH0a95aWwqugAM7OznAqKoLTDz9UX0pK4OTkBKdz56pjP/0kxoqLpblarRj/+efq2I8/irE//5Tm/vGHGP/lF2ncyQlON29KY9evi/HcXGncwQFO5eXS2NWrYu6vv0rjajWcKiulscuXxdyLF6VxpRJOer00VlAg5l66JI0D4qVm7NIlMbegQBJ31uvhqFTC5ezZ6vjFi2Lu5ctiztmz8Pr1V9zr7o4/rl9HVcuW1X3r21ds5rx51TEHB+CLL4DSUmmse3cxd/Fiafw//xHjNWMhIWJs5UppfNs2MV6zhsBAMbZhgzR30yYx7udXHTMMr4mJ0ty1a8V4+/bVMRcXMbZjhzR3+XIxHh4ujVdWAikp0thLL4m5kZHSeFERcOiQJKZ8/nkAgGrQIGlufj6QmSmNPfWUuNzhw6Xx8+eB7GxpbOxYMXfsWGk8O1vMrxkbPlzMfeopaTwzU6yjZiwqSsydPVsaP3RIXL+aschIMfell6TxlBTxcasZCw8Xc5cvl8b/eo+Ai0t1rH17MbZ2rTQ3MVGMt2pVHfPzE2ObNklzN2wQ44GB1bGWLQEA/unp0Li6VsdXrhRzQ0KkywDE53HN2OLFYrx7d2m8tFR8fdSMzZsn5vbtK41fuwZkZEhj06eLuYMHS+O//gqcPi2NJSSIuaNHS+M//CBeasZGjxZzExKk8dOnxWXXjA0eLOZOny6NZ2SINdeMWeA9QrF7NwBIeyHD9wjMni3mRkVJ4435HvH445A7hSDUHJOpPrRaLTw8PHCtoABeXl5i8K+/2spKSpB74QICAwLg7OxsH1v1mvkWQG1REdzd3W+7BdDgZlkZ8n79Fe38/eHk6Fid29S27NjpX/e6qirsO3AAQ2JioDH85X275XILoOVyb9NPHYB9qakYEhtbfe45O3ieyHELoE6vx779+zEkOlp6HkCZvUfYwxZAbXExPLy8UPTX/xtyxI+ALUGjES81qdWAQgGF4UUMVA8ktzL1PYT2kGvIr+sybJmr11fHbl2XW3IVhtvV6tp9U6nEy61MnbTVHnKVStO9MzfX1OMIVL+R1jX31mXXZ7m3q81aufbQT2vk6nTiY27qfcpenifm5N6uNnt8nhgGKVO9kOt7hDm5t6utLrm3y5ERfgRMREREJDMcAImIiIhkhgMgmTRt2jSMGzfO1mUQERGRFXAAJJNWrFiBzZs3N/j+kydPxqJFiySxzMxMqFQqDB061NzyiIiIyAwcAMkkT09PuLq6Nui+VVVVSE1NRXx8vCSemJiIWbNmISMjA/n5+ZYok4iIiBqAAyDVkpeXB4VCgby8vAbd//jx49BoNOhuOBcWgJKSEuzcuRPTp0/H0KFDsXXrVssUS0RERPXGAZBqyc7ORsuWLRFoOOloPaWkpCAuLk7yVWu7du1CcHAwgoKCMH78eGzZsgU8BSUREZFtcACkWrKystClS5cG3z85Odnkx7/jx48HAAwaNAhFRUU4fPiwWXUSERFRw/BMiDZ2Ku86Vh34EcVllvleQjcnDRbEBqFboGeDl5GdnY1ww9dY1dPZs2eRn5+PgQMHGmPnzp3DyZMn8fnnnwMA1Go1xowZg8TERPTr16/BdRIREVHDcAC0sfeP/Bcnc29YfJnmDIBZWVkYNmwYSkpKMHr0aFy6dAkAsHr1asTGxmLp0qXYsWMH2rRpA0dHR8yYMQPDhg0DIH78Gx0dDScnJ+PyEhMTUVlZCT/Dd5gCEAQBjo6O2LhxIzw8PBpcKxEREdVfkxwAV6xYgd27d+PHH3+Es7MzevbsiTfeeANBQUHGnH79+tX6iHHatGnYZPjSbAAXLlzA9OnTkZ6ejhYtWiAhIQErVqyAuhG/ImZq7/txo7TColsAp/a+v8H312q1yMvLQ3h4OA4cOAAvLy/s378fgiCguLgYX3/9Nfbu3YucnBxcv34dHTt2xIwZM4z3T05OxtNPP228XllZiW3btmHNmjWIiYmR/K4RI0Zgx44deOaZZxpcLxEREdVfkxwADx8+jBkzZqB79+6orKzEwoULERMTgx9++EFy6pKpU6fi1VdfNV53cXEx/lxVVYWhQ4fCx8cHx48fR0FBASZOnAiNRoPXX3+90dalW6Andk3r2Wi/726ys7OhUqnQqVMntGjRAnPmzMGCBQswcuRIREZG4tixYxg5ciQcHR3h6+uLAQMGGO975coVnDp1CikpKcZYamoqbty4gSlTptTa0jdq1CgkJiZyACQiImpkTfIgkP3792PSpEno1KkTwsLCsHXrVly4cAGnT5+W5Lm4uMDHx8d4cXd3N9725Zdf4ocffsBHH32E8PBwDB48GMuXL8fbb7+NioqKxl4lu5GdnY3g4GA4OjqiQ4cOyMrKQqdOnTB37lxs3LgRACRH99a0Z88eREREwNvb2xhLTExEVFSUyY95R40ahVOnTiEnJ8c6K0NEREQmNcktgLcqKioCIJ68uKaPP/4YH330EXx8fBAXF4dXXnnFuBUwMzMToaGhaN26tTE/NjYW06dPx/fff4+//e1vtX5PeXk5ysvLjde1Wi0AQKfTQafTSXJ1Oh0EQYBer4der7fMijaCZ599Fs8++yz0ej3y8/Ph6emJCRMmwMHBAQcPHsS0adMwa9YsPP/887h+/TrS09MxadIk6PV6JCUlIS4uTrK+ycnJAGDyMejWrRuqqqpue3t9GE4pY3jM70Sv10MQBOh0OqhUKrN+L9VmeC3c+pog22A/7Ad7YT/Yg2YwAOr1esyZMwcPP/wwOnfubIw/8cQTCAgIgJ+fH3JycvDiiy/i3Llz2L17NwCgsLBQMvwBMF4vLCw0+btWrFiBZcuW1Yqnp6dLPl4GxCNdfXx8UFJS0mS3KH711Vd45ZVXoFKp4OzsjLfeegsdOnRA//79ERoaCl9fX3Tt2hWlpaXQarXo1q0bhg4dahyMbaG4uPiuORUVFbh58yYyMjJQWWmZfS+ptrS0NFuXQDWwH/aDvbC90tJSW5dgcwqhiZ+Nd/r06fjiiy9w9OhRtG3b9rZ5//u//4uBAwfi/PnzeOCBB/D000/j119/xYEDB4w5paWlcHV1xb59+zB48OBayzC1BdDf3x8FBQXw8vKS5JaVleHixYsIDAyUHBHb3EyePBmjRo0yHgVsK4aDVNzc3G77EbVBWVkZ8vLy4O/v36x7Yys6nQ5paWmIjo6GRqOxdTmyx37YD/bCfmi1Wnh7e6OoqEiye5icNOktgDNnzkRqaioyMjLuOPwBQI8ePQDAOAD6+Pjg5MmTkpzLly8DAHx8fEwuw9HREY6OjrXiGo2m1ou5qqoKCoUCSqUSSmWT3NWyTuxlHQ0f+xrquROlUgmFQmGyb2Q5fHztC/thP9gL2+Pj30QPAhEEATNnzsTnn3+O//3f/0W7du3uep+srCwAgK+vLwAgMjISZ86cwZUrV4w5aWlpcHd3R0hIiFXqbo62bt1q861/REREVD9NcgvgjBkzsH37diQnJ8PNzc24z56HhwecnZ3xyy+/YPv27RgyZAi8vLyQk5OD559/Hn369DF+xVlMTAxCQkIwYcIErFq1CoWFhVi0aBFmzJhhcisfERERUXPRJLcAvvvuuygqKkK/fv3g6+trvOzcuRMAjEesxsTEIDg4GPPmzcOoUaOwZ88e4zJUKhVSU1OhUqkQGRmJ8ePHY+LEiZLzBhIRERE1R01yC+Ddjlvx9/ev9S0gpgQEBGDfvn2WKouIiIioSWiSWwCJiIiIqOE4ABIRERHJDAdAIiIiIpnhAEhEREQkMxwAiYiIiGSGAyARERGRzHAAJCIiIpIZiw2A3333naUWRURERERWZNYAWFxcjM2bNyMiIgJhYWGWqomaOMOJupcuXSq5TkRERPahQQNgRkYGEhIS4Ovri9WrV2PAgAE4ceKEpWujJurdd9/F5s2b8eeff+Kll15CRkaGrUsiIiKiGuo8ABYWFmLlypVo3749Hn30Ubi7u6O8vBxJSUlYuXIlunfvbs06qZFNmzYN48aNa9B9n332WRQVFeGtt95CXFwc+vbta+HqiIiIyBx1GgDj4uIQFBSEnJwcrF+/Hvn5+diwYYO1ayMbWrFiBTZv3tyg+27atAkeHh6YPXs29uzZgyNHjpjMmzx5MhYtWiSJZWZmQqVSYejQoQ363URERHR36rokffHFF5g9ezamT5+O9u3bW7smsgOenp4Nvu+0adOgUCiwdOlSLF261OQ+gFVVVUhNTcXevXsl8cTERMyaNQuJiYnIz8+Hn59fg+sgIiIi0+q0BfDo0aMoLi5G165d0aNHD2zcuBHXrl2zdm1kI3l5eVAoFMjLy2vQ/RUKBYDqg0AM12s6fvw4NBqNZNeBkpIS7Ny5E9OnT8fQoUOxdevWBv1+IiIiurM6DYAPPfQQ3n//fRQUFGDatGn45JNP4OfnB71ej7S0NBQXF1u7TmpE2dnZaNmyJQIDA632O1JSUhAXFycZDnft2oXg4GAEBQVh/Pjx2LJlC48gJiIisoI6fQRs4OrqiieffBJPPvkkzp07h8TERKxcuRIvvfQSoqOjkZKSYq06m68LJ4CDy4ByCw3RTu7AwMXAfQ81eBFZWVno0qWLZeq5jeTkZKxbt04SS0xMxPjx4wEAgwYNQlFREQ4fPox+/fpZtRYiIiK5qdcAWFNQUBBWrVqFFStWYM+ePdiyZYsl65KP4xuAC8ctv0wzBsDs7GyEh4dbrp5bnD17Fvn5+Rg4cKAxdu7cOZw8eRKff/45AECtVmPMmDFITEzkAEhERGRhdRoAFy9ejOHDh6Nr1661blOpVBgxYgRGjBhh6doaxdtvv41//etfKCwsRFhYGDZs2ICIiIjGK6DnLKD0umW3APacZdYisrKyMGzYMMvUY0JKSgqio6Ph5ORkjCUmJqKyslJy0IcgCHB0dMTGjRvh4eFhtXqIiIjkpk4D4G+//YbBgwfDwcEBcXFxiI+Px8CBA+Hg4GDt+qxq586dmDt3LjZt2oQePXpg/fr1iI2Nxblz53Dvvfc2ThH3PQQ8+UXj/K460Gq1yMvLQ3h4OEpKSjB69GhcunQJALB69WrExsZi6dKl2LFjB9q0aQNHR0fMmDGjXgNjcnIynn76aeP1yspKbNu2DWvWrEFMTIwkd8SIEdixYweeeeYZy6wgERER1e0gkC1btqCwsBA7duyAm5sb5syZA29vb4waNQrbtm3D9evXrV2nVaxduxZTp07F5MmTERISgk2bNsHFxUXWH2dnZ2dDpVKhU6dOOHDgALy8vHDmzBnk5OQgMjISX3/9Nfbu3YucnBx8/PHHyMzMrNfyr1y5glOnTkkGxtTUVNy4cQNTpkxB586dJZdRo0YhMTHR0qtJREQka3XeB1CpVKJ3797o3bs3Vq1ahbNnz2LPnj1477338PTTTyMiIgLx8fEYO3Ys2rRpY82aLaKiogKnT5/Gyy+/bIwplUpERUXddqgpLy9HeXm58bpWqwUA6HQ66HQ6Sa5Op4MgCNDr9dDr9VZYA+vIyspCcHAwNBoNOnXqhDlz5uCFF17AiBEjEBkZiaNHj2LEiBHQaDRo3bo1+vfvX691TE5ORkREBDw9PY33+fe//42BAwfCzc2t1nJGjhyJVatW3fXAFMPRwobH/E70ej0EQYBOp4NKpapT3VR3htfCra8Jsg32w36wF/aDPTDjIJCOHTuiY8eOWLBgAa5evYqUlBTjUcDz58+3WIHWcu3aNVRVVaF169aSeOvWrfHjjz+avM+KFSuwbNmyWvH09HS4uLhIYmq1Gj4+PigpKUFFRYXlCreyCRMmYMKECdBqtfDx8cHhw4dx4MABPP/88xg9ejSqqqpQXl5uHH4rKytRWlpqvH43u3fvRnR0tCT/o48+AgCTywgODsaNGzdue/ut6nJKooqKCty8eRMZGRmorKysU91Uf2lpabYugWpgP+wHe2F7paWlti7B5ho8ANbUqlUrTJkyBVOmTLHE4uzWyy+/jLlz5xqva7Va+Pv7o3///vDy8pLklpWV4eLFi2jRooXkYIemJD8/Hz4+Ppg2bRpatmyJgwcPYtq0aZg1axYWLlyI69ev4+jRo5g6dSrc3d3rtMx+/frh8ccfr3N+XQmCgOLiYri5uZk88XRNZWVlcHZ2Rp8+fZpsb+yZTqdDWloaoqOjodFobF2O7LEf9oO9sB913WjRnJk1AO7bt++Otw8ZMsScxVuVt7c3VCoVLl++LIlfvnwZPj4+Ju/j6OgIR0fHWnGNRlPrxVxVVQWFQgGlUgmlsk67Wtqd77//HvPnz4dKpYKzszMSExMREhKCwYMHIywsDG3atMFDDz1Ur3V88cUXrVKr4WNfw2N+J0qlEgqFwmTfyHL4+NoX9sN+sBe2x8ffzAFw48aNyMzMxMCBAyEIAtLT0xEZGYl7770XCoXCrgdABwcHdO3aFYcOHTKewkav1+PQoUOYOXOmbYuzE7GxsYiNja0VN3zHLwBMmjSpcYsiIiIis5k1AFZUVODs2bPGLWaFhYUYP348PvjgA4sUZ21z585FQkICunXrhoiICKxfvx5//vknJk+ebOvSiIiIiKzGrAHwt99+g7e3t/G6l5cXfvvtN7OLaixjxozB1atXsXjxYhQWFiI8PBz79++vdWAI3d7WrVttXQIRERHVk1kD4OOPP46HH34YI0eOBAAkJSVh7NixFimsscycOZMf+RIREZGsmDUALl26FMOGDcOxY8cAAO+88w7+/ve/W6QwIiIiIrIOsw5PTUtLQ3BwMJ577jmo1Wps2rTptufQIyIiIiL7YNYAOH/+fLRo0QInTpzA9u3bERUV1ezPBUhERETU1FnkBHVJSUl45pln8Nhjj/Hs2kRERER2zqx9AP38/DBhwgRkZGQgKysL5eXlqKqqslRtRERERGQFd90COGHCBNy8eRMAcOHCBcltn332GUaOHImDBw/innvuwfXr17F69WrrVEpEREREFnHXLYCurq4oLy+Hs7MzAgMDcc8996BLly4IDw9HWFgYwsPDERgYCADw9fWFr6+vtWsmIiIiIjPcdQDctGmT8efc3FxkZ2cjKysL2dnZSElJQV5eHtRqNYKDg5GdnW3VYomIiIjIfPXaBzAgIAABAQGIj483xoqLi5GVlYWcnByLF0dERERElmfWQSAA4Obmht69e6N3796WqIfsxLRp01BSUoKPP/7Y1qUQERGRhVnkNDDU/KxYsQKbN2+2dRm1TJ48GYsWLTJez8zMhEqlwrBhw2xYFRERUdPCAZBM8vT0hKurq63LkKiqqkJqaqpkF4TExETMmjULR44cQUFBgQ2rIyIiajo4AFIteXl5UCgUyMvLs3UpEsePH4dGo0H37t0BACUlJdi5cyemT5+OIUOGYPv27TaukIiIqGngAEi1ZGdno2XLlsbT+9iLlJQUxMXFQaFQAAB27dqF4OBgBAUFYdy4cfj4448hCIKNqyQiIrJ/HACplqysLHTp0sXWZdSSnJxc6+Pf8ePHAwAGDRoErVaLw4cP26o8IiKiJoMDoD2oqgJ0uuqLXi/Ga8Z0urrlWuCr+LKzsxEeHm72cizp7NmzyM/Px8CBAwEA586dw8mTJzF27FgAgFqtxsiRI7FlyxZblklERNQkcAC0B8uXAw4O1ZcdO8S4i0t1rH17MbZ2rTQ3MVGMt2olXl++3OxysrKyEBYWhpKSEgwaNAihoaEIDQ3FgQMHAABLly5FUFAQBgwYgMGDByM1NRWAuO9gWFgYxo0bh/bt22P69OlISkpCjx490LlzZ/z888/G3zFs2DB07doVnTt3Np5qJjMzExEREaisrMTly5fRvn17FBYWAhA//o2OjoaTkxMAcetfZWUl/Pz8oFar4eDggC1btmD37t0oKioy+zEgIiJqzprcAJiXl4cpU6agXbt2cHZ2xgMPPIAlS5agoqJCkqNQKGpdTpw4IVnWp59+iuDgYDg5OSE0NBT79u1r7NURvfIKUFFRfflrqxZKS6tjhuFp7lxp7pQpYvzqVfH6K6+YVYpWq0VeXh7Cw8Nx4MABeHl54cyZM8jJyUFkZCS+/vpr7N27Fzk5Ofj444+RmZkpuf/Zs2exePFi/Pjjj/i///s/HDt2DF999RVmzZqFjRs3GvO2bduG06dP46uvvsI///lPlJeXIzIyEn369MEbb7yBGTNmYPHixfDx8QEgfvw7fPhwAEBlZSW2bduGNWvWICsrC1lZWfjmm29w5MgR+Pn5YYdhgCYiIiKTmtwA+OOPP0Kv1+O9997D999/j3Xr1mHTpk1YuHBhrdyDBw+ioKDAeOnatavxtuPHj2Ps2LGYMmUKvv32W4wYMQIjRozAd99915irI1KpAI2m+qL8qy01YxpN3XJVKrNKyc7OhkqlQqdOnRAaGoqMjAwsWLAAJ06cgLu7O44dO4aRI0fC0dERvr6+GDBggOT+QUFBCAoKgkqlQseOHREVFQUACA0NlRxVvG7dOoSFhaFnz564cOECLly4AAB47bXX8D//8z8oKyvDhAkTAABXrlzBqVOnjOf6S01NxY0bNzBlyhR07tzZeAkJCcEjjzyCRMNWUSIiIjKpyQ2AgwYNwgcffICYmBjcf//9iI+Px/z587F79+5auV5eXvDx8TFeNIYhCsCbb76JQYMG4YUXXkDHjh2xfPly/P3vf5dspZKj7OxsBAcHw9HRER06dEBWVhY6deqEuXPnGh8bw1G4pjg6Ohp/ViqVxutKpRJVf+2fmJ6ebtwyaPh95eXlAMRhr6KiAteuXTPm79mzBxEREfD29gYgfvwbFRUFDw+PWr//kUcewalTp/jVhERERHfQ5AZAU4qKiuDp6VkrHh8fj3vvvRe9evVCSkqK5LbMzEzj1imD2NjYWh9pys3MmTNx5swZAEB+fj5cXV2RkJCAOXPmICsrC7169UJSUhIqKipQWFiI9PT0ev8OrVYLLy8vODk5ISsrC9nZ2cbbpk6dig0bNqB79+5Ys2YNgNpH/+7Zswd79+41ueyIiAgIgmCXRzETERHZC7O/C9jWzp8/jw0bNmD16tXGWIsWLbBmzRo8/PDDUCqV+M9//oMRI0YgKSnJOEgUFhaidevWkmW1bt3aeNCBKeXl5cYtVYA4yACATqeDznCU7l90Oh0EQYBer4fecKRuE5OdnY0FCxZApVLB2dkZ77//PkJCQowHhrRp0wY9evQwrqNhPQ3/1lx/vV5vvB4TE4N33nkHISEhCAkJQdeuXaHX6/H++++jVatWGDx4MPr06YOHHnoIcXFxePjhhzFmzJg7Po6G8/8ZfsedGGrR6XRQmfmROdVmeC3c+pog22A/7Ad7YT/YA0Ah2MmZc1966SW88cYbd8w5e/YsgoODjdcvXbqEvn37ol+/fvj3v/99x/tOnDgRubm5OHLkCADAwcEBH374ofE0IgDwzjvvYNmyZbh8+bLJZSxduhTLli2rFd++fTtcXFwkMbVaDR8fH/j7+8PBweGOtTVlzz77LOLj4zFo0CBbl1JnFRUVuHjxIgoLC1FZWWnrcoiIqJGVlpbiiSeeQFFREdzd3W1djk3YzRbAefPmYdKkSXfMuf/++40/5+fno3///ujZsyc2b9581+X36NEDaWlpxus+Pj61Br3Lly8bjzo15eWXX8bcuXON17VaLfz9/dG/f394eXlJcsvKynDx4kW0aNHCeOqS5kij0cDFxcXmLyBBEFBcXAw3N7c77qMIiL1xdnZGnz59mnVvbEWn0yEtLQ3R0dGS/W7JNtgP+8Fe2A/DJ3hyZjcDYKtWrdCqVas65V66dAn9+/dH165d8cEHH0CpvPuujFlZWfD19TVej4yMxKFDhzBnzhxjLC0tDZGRkbddhqOjo+QgBwONRlPrxVxVVQWFQgGlUlmn+pqqDz/80NYlAKj+2NnwmN+JUqmEQqEw2TeyHD6+9oX9sB/she3x8bejAbCuLl26hH79+iEgIACrV6/G1atXjbcZtt59+OGHcHBwwN/+9jcAwO7du7FlyxbJx8TPPfcc+vbtizVr1mDo0KH45JNPcOrUqTptTSQiIiJqyprcAJiWlobz58/j/PnzaNu2reS2mrszLl++HL/++ivUajWCg4Oxc+dOjB492nh7z549sX37dixatAgLFy5E+/btkZSUhM6dOzfauhARERHZQpMbACdNmnTXfQUTEhKQkJBw12U9+uijePTRRy1UGREREVHT0Hx3TiMiIiIikzgAEhEREckMB0Ara6ongW7O2BMiIpK7JrcPYFPh4OAApVKJ/Px8tGrVCg4ODnc9Px01nF6vR0VFBcrKym57GhhBEFBRUYGrV69CqVQ26xN0ExER3QkHQCtRKpVo164dCgoKkJ+fb+tymj1BEHDz5k04OzvfddB2cXHBfffd16zPz0hERHQnHACtyMHBAffddx8qKytRVVVl63KaNZ1Oh4yMDPTp0+eOJ/hUqVRQq9XcGktERLLGAdDK+I0TjUOlUqGyshJOTk58rImIiO6Cn4ERERERyQwHQCIiIiKZ4QBIREREJDPcB9ASdDrxAgAqFaBUVl830GiAqiqg5jno6pOrVIr5pnL1ejHfkrlqNSAIpnMrK8Xb7pSrUIhxc3MBMX63XL1evF5zPW6Xq1KJt5larqke3ZoLmN/P5tx7w8+3PmbW6n19cs3tfVN8ngBiXs24PTxPGvs94k79bKz3CMPPcn+PsNTzBGj4e8St/ZIjgRqsqKhIACAUiU818fLRR+KNanV1LCBAjK1aVR0DBGHzZjHu4VEd8/YWYxs3SnPXrRPjfn7VMRcXMfbBB9Lc114T4w8+KI0LgiDs2iWNLVwoxsPCpPGSEkFITZXGnntOzO3ZUxq/ckUQ0tOlsaeeEnOjoqTx3FxBOHlSGnviCTF3+HBp/LvvxEvN2PDhYu4TT0jiuuPHhQPvvSfNjYoSc596ShpPTxdrrhnr2VPMfe45aTw1VXwsasbCwsTchQul8V27xHjN2IMPirHXXpPGP/hAjLu4VMf8/MTYunXS3I0bxbi3d3XMw0OMbd4szV21SowHBFTH1Gox9tFH0twlS8R4SIg0XlEhCJ9/Lo3Nny/mdusmjd+4IQhffimJVT7zjJCUlCRU9ekjzf3tN0E4elQaS0gQlztkiDT+00+C8O230tjo0WLu6NHS+Lffivk1Y0OGiLkJCdL40aNiHTVjffuKuc8+K41/+aW4fjVj3bqJufPnS+Offy4+bjVjISFi7pIl0ngjv0dUVFQIp2fNkubK8D1COHlSXHbNWCO/R+i2bxeSkpKkuTJ8jxCefVbM7dtXGm/E94ii6GgBgFBUVCTIlUIQBMHWQ2hTpdVq4eHhgWsFBfDy8hKD3AokauS/7nV6PfZ98QWGxMRUHwXMLYANyzWz97qqKuw7cEDshaGHt1sutwBaLvc2/dQB2JeaiiGxsdWvDTt4nshxC6BOr8e+/fsxJDpaerYCmb1H2MMWQG1xMTy8vFBUVAR3d3fIET8CtgSNRrzcGruVSiVeTN3fnFylUrxYOlehMJ2rNvG0sVbu7Wq7NVenE5drqhf1Wa61eiTX3t+6bGv03lK59tBPa+TqdOJjXtf3qeb6HmGpXHN6ZBikTPVCru8R5uTerra65N4uR0Z4EAgRERGRzHAAJCIiIpIZDoBEREREMsMBkIiIiEhmOAASERERyQwPgzGD4Qw6xcXF0kP6qdHpdDqUlpZCq9WyFzbGXtgX9sN+sBf2Q6vVAqj+f1yOOACa4ffffwcAtGvXzsaVEBERUX0VFxfDw8PD1mXYBAdAM3h6egIALly4INsnkL3QarXw9/fHxYsXZXtST3vBXtgX9sN+sBf2QxAEFBcXw8/Pz9al2AwHQDMo/zpZpYeHB1/MdsLd3Z29sBPshX1hP+wHe2Ef5L7hhgeBEBEREckMB0AiIiIimeEAaAZHR0csWbIEjo6Oti5F9tgL+8Fe2Bf2w36wF2RPFIKcj4EmIiIikiFuASQiIiKSGQ6ARERERDLDAZCIiIhIZjgAEhEREckMB0AiIiIimeEASERERCQzHACJiIiIZIYDIBEREZHMcAAkIiIikhkOgEREREQywwGQiIiISGY4ABIRERHJDAdAIiIiIplR27qApkyv1yM/Px9ubm5QKBS2LoeIiIjqQBAEFBcXw8/PD0qlPLeFcQA0Q35+Pvz9/W1dBhERETXAxYsX0bZtW1uXYRMcAM3g5uYGAMjNzYWnp6eNq5E3nU6HL7/8EjExMdBoNLYuR9bYC/vCftgP9sJ+aLVa+Pv7G/8flyMOgGYwfOzr5uYGd3d3G1cjbzqdDi4uLnB3d+cbq42xF/aF/bAf7IX9kfPuW/L84JuIiIhIxjgAEhEREckMB0AiIiIimeEASERERCQzHACJiIiIZIYDIBEREZHMcAAkIiIikhkOgEREREQywwGQiIiISGY4ABIRERHJDAdAIiIiIpnhAEhEREQkMxwAiYiIiGSGAyARERGRzHAAJCIiIpIZDoBEREREMsMBkIiIiEhmOAASERERyQwHQCIiIiKZ4QBIREREJDMcAImIiIhkhgMgERERkcxwACQiIiKSGQ6ARERERDLDAZCIiIhIZtQNvWNFRQWSkpKQmZmJwsJCAICPjw969uyJ4cOHw8HBwWJFEhEREZHlNGgL4Pnz59GxY0ckJCTg22+/hV6vh16vx7fffouJEyeiU6dOOH/+vKVrJSIiIiILaNAWwOnTpyM0NBTffvst3N3dJbdptVpMnDgRM2bMwIEDByxSJBERERFZToMGwGPHjuHkyZO1hj8AcHd3x/Lly9GjRw+ziyMiIiIiy2vQR8AtW7ZEXl7ebW/Py8tDy5YtG1gSEREREVlTg7YAPvXUU5g4cSJeeeUVDBw4EK1btwYAXL58GYcOHcJrr72GWbNmWbRQIiIiIrKMBg2Ar776KlxdXfGvf/0L8+bNg0KhAAAIggAfHx+8+OKLWLBggUULJSIiIiLLaPBpYF588UW8+OKLyM3NlZwGpl27dhYrjoiIiIgsr8EDoEG7du049BERERE1IfwmECIiIiKZ4QBIREREJDOyHgCXLl0KhUIhuQQHB9u6LCIiIiKrMnsfwKauU6dOOHjwoPG6Wi37h4SIiIiaObOnnT/++AMnT57ElStXoNfrJbdNnDjR3MVbnVqtho+Pj63LICIiImo0Zg2Ae/bswbhx41BSUgJ3d3fj+QABQKFQNIkB8Oeff4afnx+cnJwQGRmJFStW4L777rN1WURERERWY9YAOG/ePDz55JN4/fXX4eLiYqmaGk2PHj2wdetWBAUFoaCgAMuWLUPv3r3x3Xffwc3NrVZ+eXk5ysvLjde1Wi0AQKfTQafTNVrdVJvh8WcfbI+9sC/sh/1gL+wHewAoBEEQGnpnV1dXnDlzBvfff78la7KZP/74AwEBAVi7di2mTJlS6/alS5di2bJlteLbt29vkgMwERGRHJWWluKJJ55AUVER3N3dbV2OTZi1BTA2NhanTp1qNgNgy5Yt0aFDB5w/f97k7S+//DLmzp1rvK7VauHv74/+/fvDy8urscokE3Q6HdLS0hAdHQ2NRmPrcmSNvbAv7If9YC/sh+ETPDkzawAcOnQoXnjhBfzwww8IDQ2t9YSOj483q7jGVlJSgl9++QUTJkwwebujoyMcHR1rxTUaDV/MdoK9sB/shX1hP+wHe2F7fPzNHACnTp0KAHj11Vdr3aZQKFBVVWXO4q1u/vz5iIuLQ0BAAPLz87FkyRKoVCqMHTvW1qURERERWY1ZA+Ctp31pan777TeMHTsWv//+O1q1aoVevXrhxIkTaNWqla1LIyIiIrIaWZ/1+JNPPrF1CURERESNzuyvgjt8+DDi4uLw4IMP4sEHH0R8fDyOHDliidqIiIiIyArMGgA/+ugjREVFwcXFBbNnz8bs2bPh7OyMgQMHYvv27ZaqkYiIiIgsyKyPgP/5z39i1apVeP75542x2bNnY+3atVi+fDmeeOIJswskIiIiIssyawvgf//7X8TFxdWKx8fHIzc315xFExEREZGVmDUA+vv749ChQ7XiBw8ehL+/vzmLJiIiIiIrMfu7gGfPno2srCz07NkTAHDs2DFs3boVb775pkUKJCIiIiLLMmsAnD59Onx8fLBmzRrs2rULANCxY0fs3LkTw4cPt0iBRERERGRZZp8HcOTIkRg5cqQlaiEiIiKiRmD2eQCJiIiIqGmp9xZAT09P/PTTT/D29sY999wDhUJx29zr16+bVRwRERERWV69B8B169bBzc3N+POdBkAiIiIisj/1HgATEhKMP0+aNMmStRARERFRIzBrH0CVSoUrV67Uiv/+++9QqVTmLJqIiIiIrMSsAVAQBJPx8vJyODg4mLNoIiIiIrKSBp0G5q233gIAKBQK/Pvf/0aLFi2Mt1VVVSEjIwPBwcGWqZCIiIiILKpBA+C6desAiFsAN23aJPm418HBAYGBgdi0aZNlKiQiIiIii2rQAJibmwsA6N+/P3bv3o177rnHokURERERkfWY9U0g6enplqqDiIiIiBqJWQeBjBo1Cm+88Uat+KpVq/Doo4+as2giIiIishKzBsCMjAwMGTKkVnzw4MHIyMgwZ9FEREREZCVmDYAlJSUmT/ei0Wig1WrNWTQRERERWYlZA2BoaCh27txZK/7JJ58gJCTEnEUTERERkZWYdRDIK6+8gkceeQS//PILBgwYAAA4dOgQduzYgU8//dQiBRIRERGRZZk1AMbFxSEpKQmvv/46PvvsMzg7O6NLly44ePAg+vbta6kaiYiIiMiCzBoAAWDo0KEYOnRorfh3332Hzp07m7t4IiIiIrIws/YBvFVxcTE2b96MiIgIhIWFWXLRRERERGQhFhkAMzIyMHHiRPj6+mL16tUYMGAATpw4YYlFExEREZGFNfgj4MLCQmzduhWJiYnQarV47LHHUF5ejqSkJB4BTERERGTHGrQFMC4uDkFBQcjJycH69euRn5+PDRs2WLo2IiIiIrKCBm0B/OKLLzB79mxMnz4d7du3t3RNRERERGRFDdoCePToURQXF6Nr167o0aMHNm7ciGvXrlm6NiIiIiKyggYNgA899BDef/99FBQUYNq0afjkk0/g5+cHvV6PtLQ0FBcXW7pOIiIiIrIQs44CdnV1xZNPPomjR4/izJkzmDdvHlauXIl7770X8fHxlqqRiIiIiCzIYucBDAoKwqpVq/Dbb79hx44dllosEREREVmYRU8EDQAqlQojRoxASkqKpRdNRERERBZg8QGQiIiIiOwbB0AiIiIimeEASERERCQzHACJiIiIZIYDIBEREZHMcAAkIiIikhkOgEREREQywwGQiIiISGY4ABIRERHJDAdAIiIiIpnhAEhEREQkM7IfAN9++20EBgbCyckJPXr0wMmTJ21dEhEREZFVyXoA3LlzJ+bOnYslS5bgm2++QVhYGGJjY3HlyhVbl0ZERERkNbIeANeuXYupU6di8uTJCAkJwaZNm+Di4oItW7bYujQiIiIiq1HbugBbqaiowOnTp/Hyyy8bY0qlElFRUcjMzDR5n/LycpSXlxuva7VaAIBOp4NOp7NuwXRHhseffbA99sK+sB/2g72wH+yBjAfAa9euoaqqCq1bt5bEW7dujR9//NHkfVasWIFly5bViqenp8PFxcUqdVL9pKWl2boE+gt7YV/YD/vBXtheaWmprUuwOdkOgA3x8ssvY+7cucbrWq0W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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Time Plots\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#%matplotlib notebook\n",
    "# Alternatively for Visual Studio Code use:\n",
    "%matplotlib widget\n",
    "import gym_electric_motor as gem\n",
    "# instantiate a finite control set current controlled PMSM\n",
    "env = gem.make(\"Finite-CC-PMSM-v0\")  \n",
    "visu = env.visualizations[0]\n",
    "visu.initialize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\jakobeit\\Anaconda3\\envs\\GEMUpdate\\lib\\site-packages\\gymnasium\\utils\\passive_env_checker.py:159: UserWarning: \u001b[33mWARN: The obs returned by the `reset()` method is not within the observation space.\u001b[0m\n",
      "  logger.warn(f\"{pre} is not within the observation space.\")\n",
      "c:\\Users\\jakobeit\\Anaconda3\\envs\\GEMUpdate\\lib\\site-packages\\gymnasium\\utils\\passive_env_checker.py:159: UserWarning: \u001b[33mWARN: The obs returned by the `step()` method is not within the observation space.\u001b[0m\n",
      "  logger.warn(f\"{pre} is not within the observation space.\")\n"
     ]
    }
   ],
   "source": [
    "terminated = True\n",
    "\n",
    "for _ in range(10000):\n",
    "    if terminated:\n",
    "        # Reset the environment\n",
    "        # This is required initally or after an episode end due to a constraint violation in the env.\n",
    "        (state, references), _ = env.reset()\n",
    "    # Visualization of environment: Red vertical lines indicate a constraint violation and therefore, a reset environment.\n",
    "    # Blue vertical lines indicate an additional reset by the user which is not due to a terminated episode.\n",
    "    env.render()\n",
    "    # pick random control actions\n",
    "    action = env.action_space.sample()\n",
    "    # Execute one control cycle on the environment\n",
    "    (states, references), rewards, terminated, truncated, _ = env.step(action)  "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Comprehensive learning material to RL is [freely available](https://github.com/upb-lea/reinforcement_learning_course_materials).\n",
    "\n",
    "### 1.5 Environment Ids\n",
    "\n",
    "In general, all environment-ids are structured as follows:\n",
    "\n",
    "    `ControlType-ControlTask-MotorType-VersionID`\n",
    "\n",
    "   * The `ControlType` is in {`Finite` / `Cont`} for all DC Motors and in {`Finite` / `AbcCont` / `DqCont`} for all AC Motors. It selects between Finite and Continuous Control set actions (in the abc or dq-Coordinate System).\n",
    "\n",
    "   * The ControlTask is in {`TC` / `SC` / `CC`} (Torque / Speed / Current Control)\n",
    "\n",
    "   * The MotorType is in {`PermExDc` / `ExtExDc` / `SeriesDc` / `ShuntDc` / `PMSM` / `SynRM` / `DFIM` / `SCIM`, `EESM` }\n",
    "   \n",
    "   * The Version of all environments is currently 0. Therefore the VersionID equals `v0`. Future versions will be named `v1, v2,...`.\n",
    "    \n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Customize a PMSM Environment"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 Make keyword arguments\n",
    "Using the keyword arguments in the `gem.make(id, **kwargs)` function you can select different function modules for the \n",
    "environment and parametrize these modules. \n",
    "The main level modules of each GEM-environment consists of the following function modules:\n",
    "\n",
    "* supply(env-arg)\n",
    "* converter(env-arg)\n",
    "* motor(env-arg)\n",
    "* load(env-arg)\n",
    "* ode_solver(env-arg)\n",
    "* noise_generator(env-arg)\n",
    "* reward_function(env-arg)\n",
    "* reference_generator(env-arg)\n",
    "* visualization(env-arg)\n",
    "* constraints(iterable(str/Constraint))\n",
    "* calc_jacobian(bool)\n",
    "* tau(float)\n",
    "* state_filter(list(str))\n",
    "* callbacks(list(Callback))\n",
    "* physical_system_wrappers(iterable(PhysicalSystemWrapper))\n",
    "* render_mode(str)\n",
    "\n",
    "#### Environment-arg type:\n",
    "The `env-arg` type is a short notation for all parameters that can be passed in three different ways to override the default behavior. Exemplary, it is shown how to change the reference generator of an environment in three different ways:\n",
    "\n",
    "* Passing an instantiated object\n",
    "  * `my_reference_generator = SinusoidalReferenceGenerator(amplitude_range=(0.2,0.8))`\n",
    "  * The reference generator instance will be used in the environment.\n",
    "\n",
    "* Passing a keystring **(deprecated with GEM 3.0.0)**:\n",
    "  * `my_reference_generator='SinusoidalReference'`\n",
    "  * The Sinusoidal Reference Generator will be used in the environment with its default parameters.\n",
    "  * Equals: `my_reference_generator=SinusoidalReferenceGenerator()`\n",
    "\n",
    "* Passing a parameter dictionary:\n",
    "  * `my_reference_generator=dict(reference_state='torque', sigma_range=(0.01, 0.1))\n",
    "  * Overrides default parameters of the Reference Generator that is used per default in the environment (here a WienerReferenceGenerator)\n",
    "  * Equals: `my_reference_generator=WienerReferenceGenerator(reference_state='torque', sigma_range=(0.01, 0.1))`\n",
    "\n",
    "```python\n",
    "env = gem.make('Cont-SC-PermExDc', reference_generator=my_reference_generator)\n",
    "```\n",
    "\n",
    "The available modules and specific keyword-arguments for each module can be looked up in the [API documentation](https://upb-lea.github.io/gym-electric-motor/parts/environments/environment.html)."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2  Physical System\n",
    "Each system consists of a voltage supply, a power electronic converter, an electrical motor, and the mechanical load (SCML) as shown in the above figure. Each such SCML-system is simulated by a user-defined ODE solver.\n",
    "\n",
    "#### Voltage Supply\n",
    "\n",
    "The voltage supply module provides both, DC and AC voltage supplies. \n",
    "- The DC supplies are either ideal or non-ideal voltage sources.\n",
    "- The AC supplies are either ideal single phase or ideal three-phase AC sources.\n",
    "\n",
    "More documentation regarding the voltage supplies of GEM can be found [here](https://upb-lea.github.io/gym-electric-motor/parts/physical_systems/voltage_supplies/voltage_supply.html). \n",
    "For the PMSM environment example, a non-ideal DC voltage supply is created. \n",
    "Here, the DC-link is modeled as an RC-circuit loaded from an ideal DC voltage source. \n",
    "\n",
    "The non-ideal DC supply in GEM is named 'RCVoltageSupply' and the supply_parameter(dict) consists of resistance R in ohm and capacitance C in farad\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.physical_systems.voltage_supplies import IdealVoltageSupply\n",
    "\n",
    "supply = IdealVoltageSupply(u_nominal=350)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Converter \n",
    "The converters are divided into two classes: The continuously controlled and the discretely controlled converters.\n",
    "\n",
    "In the continuous case, the agent's actions denote a duty cycle that is modulated to the converter's output voltage.\n",
    "\n",
    "In the discrete case, the agent's actions denote switching states of the converter at the given instant.\n",
    "Here, only a discrete amount of options are available. In this notebook, for the PMSM the discrete B6 bridge converter with six switches is utilized per default. This converter provides a total of eight possible actions.\n",
    "\n",
    "\n",
    "![](../../docs/plots/B6.svg)\n",
    "\n",
    "\n",
    "#### Motor \n",
    "In this tutorial, the electric motor used is the **permanent magnet synchronous motor**.\n",
    "The motor schematic is the following:\n",
    "\n",
    "\n",
    "![](../../docs/plots/ESBdq.svg)\n",
    "\n",
    "And the electrical ODEs for that motor are:\n",
    "\n",
    "<h3 align=\"center\">\n",
    "\n",
    "<!-- $\\frac{\\mathrm{d}i_{sq}}{\\mathrm{d}t} = \\frac{u_{sq}-pL_d\\omega_{me}i_{sd}-R_si_{sq}}{L_q}$\n",
    "\n",
    "$\\frac{\\mathrm{d}i_{sd}}{\\mathrm{d}t} = \\frac{u_{sd}-pL_q\\omega_{me}i_{sq}-R_si_{sd}}{L_d}$\n",
    "\n",
    "$\\frac{\\mathrm{d}\\epsilon_{el}}{\\mathrm{d}t} = p\\omega_{me}$\n",
    " -->\n",
    "\n",
    "   $ \\frac{\\mathrm{d}i_{sd}}{\\mathrm{d}t}=\\frac{u_{sd} + p\\omega_{me}L_q i_{sq} - R_s i_{sd}}{L_d} $ <br><br>\n",
    "    $\\frac{\\mathrm{d} i_{sq}}{\\mathrm{d} t}=\\frac{u_{sq} - p \\omega_{me} (L_d i_{sd} + \\mathit{\\Psi}_p) - R_s i_{sq}}{L_q}$ <br><br>\n",
    "   $\\frac{\\mathrm{d}\\epsilon_{el}}{\\mathrm{d}t} = p\\omega_{me}$\n",
    "\n",
    "</h3>\n",
    "   \n",
    "\n",
    "\n",
    "\n",
    "The motor environment ID for the finite control set current controlled PMSM motor is **\"Finite-CC-v0\"**.\n",
    "The parameters of the specific motor are to be passed by the user as a motor parameter dictionary.\n",
    "Default parameters will be considered in case the motor parameters are not provided by the user. \n",
    "The nominal and limit values which define the operating region of the motor are also passed as a dictionary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "motor_env_id = \"Finite-CC-PMSM-v0\"\n",
    "tau = 1e-5    # The duration of each sampling step\n",
    "\n",
    "# motor type: Brusa HSM16.17.12-C01\n",
    "motor_parameter = dict(\n",
    "    p=3,  # [p] = 1, nb of pole pairs\n",
    "    r_s=17.932e-3,  # [r_s] = Ohm, stator resistance\n",
    "    l_d=0.37e-3,  # [l_d] = H, d-axis inductance\n",
    "    l_q=1.2e-3,  # [l_q] = H, q-axis inductance\n",
    "    psi_p=65.65e-3,  # [psi_p] = Vs, magnetic flux of the permanent magnet\n",
    ")  \n",
    "\n",
    "nominal_values=dict(\n",
    "    omega=4000*2*np.pi/60,  # angular velocity in rpm\n",
    "    i=230,                  # motor current in amps\n",
    "    u=350                   # nominal voltage in volts\n",
    ")\n",
    "# limit values are taken exemplarily as 1.3 times the nominal values\n",
    "limit_values = {key: 1.5 * nomin for key, nomin in nominal_values.items()}\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Motor State Initializer\n",
    "By default, the motor states (e.g. motor currents, rotational speed) are always set to zero whenever the motor environment is reset. In order to generate diverse expisodes, the motor state initializer can be used to draw the initial state values from a given probability distribution within the nominal operating range of the given motor. \n",
    "\n",
    "The 'motor_initializer' is a dictionary that consists of the type of distribution, for example, uniform or gaussian distribution and the interval of values within the nominal operating region. \n",
    "Here, the motor states, i.e. $i_{sd}$, $i_{sq}$ and motor angle are initialized with values sampled from a uniform distribution from the provided intervals.\n",
    "\n",
    "$i_{sd}$ and $i_{sq}$ are the motor currents in the [d-q coordinate system](https://en.wikipedia.org/wiki/Direct-quadrature-zero_transformation#:~:text=The%20direct%2Dquadrature%2Dzero%20,an%20effort%20to%20simplify%20analysis).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "motor_initializer={'random_init': 'uniform', 'interval': [[-230, 230], [-230, 230], [-np.pi, np.pi]]}  "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Mechanical Load\n",
    "The mechanical load module in GEM models various external mechanical systems that apply counterforces on the electrical motor's rotor through the drive shaft.\n",
    "Different types of load models such as constant speed load and polynomial static load are provided. More information can be found in the [documentation.](https://upb-lea.github.io/gym-electric-motor/parts/physical_systems/mechanical_loads/mechanical_load.html)\n",
    "\n",
    "In this example, the load type: _ConstSpeedLoad_ is used. \n",
    "This initializes the load with a constant speed at the start of each episode. \n",
    "The initialization value for speed is sampled from a uniform distribution defined by the given interval."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.physical_systems import ConstantSpeedLoad\n",
    "\n",
    "load = ConstantSpeedLoad(\n",
    "    load_initializer={'random_init': 'uniform', 'interval':[100,200] }   \n",
    ")\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 Reward Function\n",
    "The reward calculation is based on the current state and reference of the motor environment. It is calculated as a weighted sum of errors with a certain power as follows:\n",
    "\n",
    "<!-- <h3 align=\"center\"> -->\n",
    "<!-- $ reward = - reward\\_weights * (abs(state - reference)/ state\\_length)^{reward\\_power}$   -->\n",
    "\n",
    "$ r_t = - \\sum \\limits_{k=0} ^{N} w_{\\{k\\}}\\big | s_{\\{k\\}t} - s^*_{\\{k\\}t} \\big |^p $   <br> <br>\n",
    "\n",
    "Here, $r_t$ is the reward at time $t$.  $ w_{\\{k\\}}$ is the reward weight for the k'th state variable of the $N$ referenced states . $s_{\\{k\\}t}$ is the k'th state variable of the motor and $s^*_{\\{k\\}t}$ is the corresponding k'th reference variable at time $t$. The reward power is $p$.\n",
    "\n",
    "\n",
    "If states are to be monitored for a constraint violation, an additional terminal reward is added. This value depends on the discount factor $\\gamma$ as follows. \n",
    "<!-- <h3 align=\"center\"> -->\n",
    "$r_t = -1 / (1 - \\gamma).$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "gamma = 0.99  #Discount factor for the reward punishment. Should equal agents' discount factor gamma.\n",
    "\n",
    "# The function that computes the reward\n",
    "rf = gem.reward_functions.WeightedSumOfErrors( \n",
    "    reward_weights={'i_sq': 10, 'i_sd': 10}, # Reward weight for each of the systems states.\n",
    "    gamma=gamma,     # Factor for the reward punishment. Should equal agent's discount factor gamma.\n",
    "    reward_power=1 # Reward power for each of the systems states\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 Constraint Monitor\n",
    "The constraint monitor monitors the system states and assesses whether they violate system boundaries specified by the constraints.\n",
    "\n",
    "The constraints can be selected from a predefined set within GEM or defined by the user.\n",
    "\n",
    "The following constraint is used for the motor currents:\n",
    "\n",
    "$ i_{sd}^2 + i_{sq}^2 > i_{max}^2 $  \n",
    "\n",
    "Here, $i_{sd}$ and $i_{sq}$ are the motor currents in the d-q coordinate system that can be accessed from the motor states and $i_{max}$ is the maximum allowable current value. This constraint can be directly accessed from the toolbox.\n",
    "\n",
    "Additionally, a user-defined constraint is put on the $i_{sd}$ current. It is not allowed to go too far into the positive direction. This is modeled as a soft constraint, that already punishes the reward, when $i_{sd}$ gets into the positive range and terminates it completely if it reaches half of $i_{max}$. \n",
    "\n",
    "(Remember: The quantities are normalized by their limit values to stay in a range of [-1,1] in the gem-environments.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "SquaredConstraint = gem.constraints.SquaredConstraint\n",
    "\n",
    "class MyConstraint(gem.constraints.Constraint):\n",
    "    \n",
    "    i_sd_idx = 0\n",
    "    \n",
    "    def set_modules(self, ps):\n",
    "        self.i_sd_idx = ps.state_positions['i_sd']\n",
    "        \n",
    "    def __call__(self, state):\n",
    "        \"\"\"This function returns a \"violation degree\" within [0,1].\n",
    "        \n",
    "        This exemplary constraint returns 0 if i_sd is 0 or below.\n",
    "        It returns a value between 0 and 1 if i_sd is at most half of the generally allowed current limit.\n",
    "        If i_sd exceeds 0.5 of the current limit, the violation degree is 1.0 and the episode will be terminated.\n",
    "        \n",
    "        The violation degree between 0 and 1 directly affects the reward, but does not end an episode.\n",
    "        It models an \"undesired behavior\" the agent shall learn to avoid.\n",
    "        \"\"\"\n",
    "        i_sd = state[self.i_sd_idx]\n",
    "        return 2 * min(max(i_sd, 0), 0.5)\n",
    "    \n",
    "def my_constraint_function(state):\n",
    "    \"\"\"This function demonstrates how a simple function can be used as a constraint. \n",
    "    \n",
    "    When no information has to be read from the environment to configure the constraint \n",
    "    (e.g. for a mapping of state names to their position in the state array), also only a function or any kind\n",
    "    of callable is sufficient that takes the state as input and returns a float within [0.0, 1.0].\n",
    "    \n",
    "    In this example, the index of the torque, that is monitored to go not too far into the negative direction, is known\n",
    "    a priori by the user. So, the \"set_env\"-function call is not necessary.\n",
    "    \"\"\"\n",
    "    \n",
    "    TORQUE_IDX = 1\n",
    "    return float(state[TORQUE_IDX] < -0.7)\n",
    "\n",
    "constraints = (SquaredConstraint(('i_sd', 'i_sq')), MyConstraint(), 'omega', my_constraint_function)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.5 Reference Generator\n",
    "The reference generator produces reference trajectories for the observed states, that the physical system is expected to follow. \n",
    "The GEM toolbox provides various reference generators, which can be found in the [documentation.](https://upb-lea.github.io/gym-electric-motor/parts/reference_generators/reference_generator.html)\n",
    "\n",
    "In this example, references to the motor currents $i_{sq}$ and $i_{sd}$ are considered.\n",
    "The \"WienerProcessReferenceGenerator\" is used to generate random references for both $i_{sq}$ and $i_{sd}$. \n",
    "\n",
    "The [Wiener process](https://en.wikipedia.org/wiki/Wiener_process) is a stochastic process $W(t)$ for $t>=0$ with $W(0)=0$ such that the increment $W(t)-W(s)$ is Gaussian with mean $0$ and variance $\\sigma$ for any $0<=s<t$, while increments for successive time steps are statistically independent.\n",
    "\n",
    "The individual sub-reference generators are then combined using the \"MultipleReferenceGenerator\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.reference_generators import \\\n",
    "    MultipleReferenceGenerator,\\\n",
    "    WienerProcessReferenceGenerator\n",
    "\n",
    "q_generator = WienerProcessReferenceGenerator(reference_state='i_sq') # sub-reference generator for i_sq\n",
    "d_generator = WienerProcessReferenceGenerator(reference_state='i_sd') # sub-reference generator for i_sd\n",
    "rg = MultipleReferenceGenerator([q_generator, d_generator])           # combine the sub-reference generators"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.6 Visualization\n",
    "The visualization module provides an interface to observe and inspect the physical system's states, references, rewards, etc. \n",
    "GEM offers two forms of visualization:\n",
    "- Motor dashboard: A graphical interface which provides visualization in the form of plots.\n",
    "- Console printer: A simpler interface in the form of console print-outs.\n",
    "\n",
    "This example demonstrates the usage of the motor dashboard for visualization.\n",
    "A list of variables to be plotted is passed to the MotorDashboard during initialization. The variables that can be plotted for a given motor environment can be found in the [documentation.](https://upb-lea.github.io/gym-electric-motor/parts/visualizations/motor_dashboard.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.visualization import MotorDashboard\n",
    "\n",
    "visualization = MotorDashboard(state_plots=['i_sq', 'i_sd', 'cos(epsilon)', 'i_abs'], reward_plot=True) \n",
    "# plots the states i_sd and i_sq and reward."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.7 ODE Solvers\n",
    "\n",
    "In GEM, all motor classes are simulated by their respective ODEs. To solve these ODEs, different solvers are available such as the EulerSolver which utilized the Euler discretization. All Scipy solvers are available using GEM's built-in wrapper classes such as `ScipyOdeSolver`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.physical_systems.solvers import EulerSolver\n",
    "ode_solver = EulerSolver()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.7 Callbacks\n",
    "GEM callbacks provide an easy-to-use interface to apply hooks on the motor environment during run time. \n",
    "Callbacks can be used to get a view of the internal states, collect statistics, or modify certain motor parameters during runtime. \n",
    "\n",
    "GEM callbacks can be used to interact with the motor environment:\n",
    "- At the start/end of every step\n",
    "- At the start/end of every reset\n",
    "- At the start of a close() call\n",
    "    \n",
    "The following example provides a sample user defined callback implementation. \n",
    "The user defined callback object must be a sub-class of the 'Callback' class as shown. \n",
    "The objective of the user defined 'RewardLogger' callback object is to create a log of the experiment's mean episode rewards.\n",
    "\n",
    "Some of the interfaces implemented here are:\n",
    "- \\__init()\\__     : A suitable class constructor.\n",
    "- on_step_end()    : A suitable task to be performed at the end of every step.\n",
    "- on_reset_begin() : A suitable task at the beginning of each episode.\n",
    "- on_close         : A suitable task at the beginning of a close.\n",
    "\n",
    "For the list of all the interfaces, check out the GEM API documentation.    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.core import Callback\n",
    "from pathlib import Path\n",
    "\n",
    "class RewardLogger(Callback):\n",
    "    \"\"\"Logs the reward accumulated in each episode\"\"\"\n",
    "    def __init__(self):\n",
    "        self._step_rewards = []\n",
    "        self._mean_episode_rewards = []\n",
    "        self.fpath = Path.cwd() /\"rl_frameworks\" / \"saved_agents\"\n",
    "        self.fpath.mkdir(parents=True, exist_ok=True)\n",
    "        \n",
    "    def on_step_end(self, k, state, reference, reward, dine):\n",
    "        \"\"\"Stores the received reward at each step\"\"\"\n",
    "        self._step_rewards.append(reward)\n",
    "    \n",
    "    def on_reset_begin(self):\n",
    "        \"\"\"Stores the mean reward received in every episode\"\"\"\n",
    "        self._mean_episode_rewards.append(np.mean(self._step_rewards))\n",
    "        self._step_rewards = []\n",
    "        \n",
    "    def on_close(self):\n",
    "        \"\"\"Writes the mean episode reward of the experiment to a file.\"\"\"\n",
    "        np.save(self.fpath / \"EpisodeRewards.npy\", np.array(self._mean_episode_rewards))\n",
    "        \n",
    "my_callback = [RewardLogger()]  # instantiate the callback object "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.8 Physical System Wrappers\n",
    "Physical System Wrappers wrap the physical system to preprocess the actions and postprocess the states of the Physical Systems.\n",
    "\n",
    "They are very similar to gym-wrappers, which are put around a gym-environment and process actions observations and rewards. The big difference between a gym-wrapper and a Physical System Wrapper is that the Physical System Wrapper is wrapped around the physical system and not around the whole environment.\n",
    "\n",
    "The ``CosSinProcessor`` in the following example adds the cosine and sine of the rotor angle ``epsilon`` to the state vector. These states can directly influence the calculated reward, or referenced by the reference generator and visualized by the dashboard (c.f. 2.6). \n",
    "\n",
    "The Physical System Wrappers are passed as iterable with the argument ``physical_system_wrappers`` as iterable (list/tuple) to the environment during the make-call (c.f. 2.9). The Physical System Wrappers can also be stacked into each other. The first processor in the list is wrapped around the physical system at first and the latter ones are put around the resulting system one after the other. Therefore, outer Physical System Wrappers access the processed states from the inner ones."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gym_electric_motor.physical_system_wrappers import CosSinProcessor, StateNoiseProcessor\n",
    "\n",
    "# \n",
    "physical_system_wrappers = [\n",
    "    # Wrapped directly around the physical system\n",
    "    CosSinProcessor(angle='epsilon'),\n",
    "    # Wrapped around the CosSinProcessor. Therefore, the generated states (cos and sin) can be accessed.\n",
    "    StateNoiseProcessor(\n",
    "        states=['cos(epsilon)', 'sin(epsilon)'],\n",
    "        random_dist='normal',\n",
    "        random_kwargs=dict(scale=0.03)\n",
    "    )\n",
    "]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.8.1 Custom Physical System Wrapper\n",
    "A custom Physical System Wrapper has to inherit from the base ``PhysicalSystemWrapper`` class. \n",
    "\n",
    "In the next cell an example of a user-defined processor is shown. \n",
    "\n",
    "In the ``__init__()`` method, additional fields can be set. \n",
    "\n",
    "The ``reset()`` method has to reset the processor and the inner system. Furthermore it has to return the initial state of the system after the reset.\n",
    "\n",
    "The ``simulate(action)`` method simulates one step of the physical system. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "import gymnasium as gym\n",
    "import numpy as np\n",
    "\n",
    "from gym_electric_motor.physical_system_wrappers import PhysicalSystemWrapper\n",
    "\n",
    "\n",
    "class CurrentVectorProcessor(PhysicalSystemWrapper):\n",
    "    \"\"\"Adds an ``i_abs`` state to the systems state vector that is the root of the squared sum of the currents ``i_sd`` and `` i_sq``.\"\"\"\n",
    "\n",
    "    def __init__(self, physical_system=None):\n",
    "        self._i_sd_idx = None\n",
    "        self._i_sq_idx = None\n",
    "        super().__init__(physical_system=physical_system)\n",
    "\n",
    "    def set_physical_system(self, physical_system):\n",
    "        \"\"\"Writes basic data like state indices to locals and finally initializes the instance.\n",
    "        \n",
    "        Args:\n",
    "            physical_system(PhysicalSystem): The inner physical system of the processor.\n",
    "            \n",
    "        Returns:\n",
    "            this: This instance.\n",
    "        \"\"\"\n",
    "        super().set_physical_system(physical_system)\n",
    "        # Define the new state space as concatenation of the old state space and [-1,1] for i_abs\n",
    "        low = np.concatenate((physical_system.state_space.low, [-1.]))\n",
    "        high = np.concatenate((physical_system.state_space.high, [1.]))\n",
    "        self.state_space = gym.spaces.Box(low, high, dtype=np.float64)\n",
    "\n",
    "        # Set the new limits /  nominal values of the state vector\n",
    "        self._i_sq_idx = self._physical_system.state_names.index('i_sq')\n",
    "        self._i_sd_idx = self._physical_system.state_names.index('i_sq')\n",
    "        current_limit = np.sqrt((physical_system.limits[self._i_sd_idx]**2 + physical_system.limits[self._i_sq_idx]**2) / 2)\n",
    "        current_nominal_value = np.sqrt((physical_system.nominal_state[self._i_sd_idx]**2 + physical_system.nominal_state[self._i_sq_idx]**2)/2)\n",
    "        self._limits = np.concatenate((physical_system.limits, [current_limit]))\n",
    "        self._nominal_state = np.concatenate((physical_system.nominal_state, [current_nominal_value]))\n",
    "\n",
    "        # Append the new state to the state name vector and the state positions dictionary\n",
    "        self._state_names = physical_system.state_names + ['i_abs']\n",
    "        self._state_positions = physical_system.state_positions.copy()\n",
    "        self._state_positions['i_abs'] = self._state_names.index('i_abs')\n",
    "        return self\n",
    "\n",
    "    def reset(self):\n",
    "        \"\"\"Resets this instance and the inner system\n",
    "        \n",
    "        Returns:\n",
    "            np.ndarray: The initial state after the reset.\"\"\"\n",
    "        state = self._physical_system.reset()\n",
    "        return np.concatenate((state, [self._get_current_abs(state)]))\n",
    "\n",
    "    def simulate(self, action):\n",
    "        \"\"\"Simulates one step of the system.\"\"\"\n",
    "        state = self._physical_system.simulate(action)\n",
    "        return np.concatenate((state, [self._get_current_abs(state)]))\n",
    "\n",
    "    def _get_current_abs(self, state):\n",
    "        \"\"\"Calculates the root sum of the squared currents from the state\n",
    "\n",
    "        Args:\n",
    "            state(numpy.ndarray[float]): The state of the inner system.\n",
    "\n",
    "        Returns:\n",
    "            float: The rms of the currents of the state.\n",
    "        \"\"\"\n",
    "        return np.sqrt(state[self._i_sd_idx]**2 + state[self._i_sq_idx]**2)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "physical_system_wrappers.append(CurrentVectorProcessor())"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.9 GEM Make Call\n",
    "\n",
    "The make function takes the environment-ids and several constructor arguments and returns an initialized environment. Every environment also works without further parameters with default values. These default parameters can be looked up in the [API-documentation](https://upb-lea.github.io/gym-electric-motor/index.html) of every GEM-environment.\n",
    "\n",
    "The various components of the motor environment defined above are passed as arguements to the ```gem.make()``` function. This further returns the discrete PMSM motor environment.\n",
    "\n",
    "The motor environment can then be passed to a reinforcement learning agent in order to learn a controller."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define a PMSM with discrete action space\n",
    "env = gem.make(  \n",
    "    motor_env_id,\n",
    "    # visualize the results\n",
    "    visualization=visualization,\n",
    "    # parameterize the PMSM and update limitations\n",
    "    motor=dict(\n",
    "        motor_parameter=motor_parameter,\n",
    "        limit_values=limit_values,\n",
    "        nominal_values=nominal_values,\n",
    "        motor_initializer=motor_initializer,\n",
    "    ),\n",
    "    # define the random initialisation for load and motor\n",
    "    load=load,\n",
    "    reward_function=rf,\n",
    "    tau=tau,\n",
    "    supply=supply,\n",
    "    reference_generator=rg,\n",
    "    ode_solver=ode_solver,\n",
    "    callbacks=my_callback,\n",
    "    physical_system_wrappers=physical_system_wrappers, # Pass the Physical System Wrappers\n",
    "    constraints=constraints\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.10 Seeding\n",
    "The random processes in the environment can be made reproducible by seeding the environments. The seeding takes place when resetting an environment, i.e. calling `env.reset(seed=seed)` with the keyword argument `seed`. "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The random generators are set to a defined state. Therefore, a new environment instance can also be initialized and seeded with this seed. Then, also the same episodes will be genrated."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 Execution of the Environment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "2e768062e0f14b96a0c8e6deea594eae",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Time Plots\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "visualization.initialize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\jakobeit\\Anaconda3\\envs\\GEMUpdate\\lib\\site-packages\\numpy\\core\\fromnumeric.py:3504: RuntimeWarning: Mean of empty slice.\n",
      "  return _methods._mean(a, axis=axis, dtype=dtype,\n",
      "c:\\Users\\jakobeit\\Anaconda3\\envs\\GEMUpdate\\lib\\site-packages\\numpy\\core\\_methods.py:129: RuntimeWarning: invalid value encountered in scalar divide\n",
      "  ret = ret.dtype.type(ret / rcount)\n"
     ]
    }
   ],
   "source": [
    "# simple routine with random actions applied\n",
    "env.reset()\n",
    "k = 0\n",
    "for i in range(int(3e4)):    \n",
    "    env.render()\n",
    "    (states, refs), rewards, terminated, truncated, _ = env.step(env.action_space.sample())  # pick random control actions\n",
    "    if terminated:\n",
    "        env.reset()\n",
    "env.close()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You will see a lot of red vertical lines indicating episode terminations. A termination is induced most of the time when limits are violated. This happens in this example very often as we apply random voltages."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "GEMUpdate",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
